﻿#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    qRegisterMetaType<qintptr>("qintptr");//注册qintptr到信号槽表示列表

    init();//调用初始化函数
}

MainWindow::~MainWindow()
{
    //释放套接字资源
    for(int i = 0;i < m_tcpSockets.count();++i){
        emit closeSocket(i);
    }

    //释放线程资源
    for(QThread* thread : m_threads){
        thread->quit();
        thread->wait();
        thread->deleteLater();
    }

    //关闭套接字监听
    m_tcpServer->close();


    delete ui;
}

void MainWindow::onReadyRead()
{

    //计算发送信号的套接字唯一标识符
    myTcpSocket* socket = (myTcpSocket*)sender();
    int index = -1;
    for(int i = 0;i < m_tcpSockets.count();++i){
        if(socket == m_tcpSockets.at(i)){
            index = i;
            break;
        }
    }
    if(index == -1){
        return;
    }


    QByteArray rec;
//    QTextStream stream(socket);
    
    //处理接收数据
    for(;socket->canReadLine();){
        rec = socket->readAll();
        if(rec.startsWith("*#getfilelist#*")){//文件列表发送模式
            rec.remove(0,15);
            rec.remove(rec.count() - 2,2);
//            qDebug() << rec;
            QDir dir(rec);
            if(dir.exists()){
                dir.setSorting(QDir::DirsFirst);
                QList<QFileInfo> files = dir.entryInfoList();

                for(QFileInfo fileInfo : files){
                    if(fileInfo.isFile()){
                        QString str = "*#sendfilename#*" + fileInfo.fileName()+"\r\n";
                        emit sendByteArray(str.toUtf8(),index);

                    }else if(fileInfo.isDir()){
                        QString str = "*#senddirname#*" + fileInfo.fileName()+"\r\n";

                        emit sendByteArray(str.toUtf8(),index);

                    }

                }
            }
        }else if(rec.startsWith("*#getfile#*")){//文件发送模式
            rec.remove(0,11);
            rec.remove(rec.count() - 2,2);
            QString filePath = QString::fromUtf8(rec);

            QFile file(filePath);

            if(file.open(QIODevice::ReadOnly)){
                for(;!file.atEnd();){
                    emit sendByteArray(file.readAll(),index);
                }
            }
        }
    }
}

void MainWindow::onNewDescript(qintptr socketDescriptor)
{
    //创建套接字
    myTcpSocket* tcpSocket = new myTcpSocket;
    m_tcpSockets.append(tcpSocket);

    //创建线程
    QThread* thread = new QThread(this);
    m_threads.append(thread);

    //移动套接字到线程
    tcpSocket->moveToThread(thread);
    thread->start();

    //关联相关信号槽
    connect(this,SIGNAL(moveDescriptToThread(qintptr,int)),tcpSocket,SLOT(onNewDescript(qintptr,int)));
    emit moveDescriptToThread(socketDescriptor,m_threads.count() - 1);
    disconnect(this,SIGNAL(moveDescriptToThread(qintptr,int)),tcpSocket,SLOT(onNewDescript(qintptr,int)));

    connect(tcpSocket,SIGNAL(socketReady(int)),this,SLOT(onSocketReady(int)));
    connect(this,SIGNAL(closeSocket(int)),tcpSocket,SLOT(onCloseSocket(int)));
    connect(this,SIGNAL(sendByteArray(QByteArray,int)),tcpSocket,SLOT(onSendByteArray(QByteArray,int)));
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(onReadyRead()));
}

void MainWindow::onSocketReady(int index)
{
    //向日志栏打印套接字加入信息
    ui->textLog->appendPlainText(m_tcpSockets.at(index)->peerAddress().toString()+":"+QString::number(m_tcpSockets.at(index)->peerPort())+"已加入连接.");


    //向新加入的套接字发送默认文件列表信息
    QDir dir(QCoreApplication::applicationDirPath());
    if(dir.exists()){
        QList<QFileInfo> files = dir.entryInfoList();
        QString s = "*#dirpath#*"+QCoreApplication::applicationDirPath()+"\r\n";
        emit sendByteArray(s.toUtf8(),index);
        for(QFileInfo fileInfo : files){
            if(fileInfo.isFile()){
                QString str = "*#sendfilename#*" + fileInfo.fileName()+"\r\n";
                emit sendByteArray(str.toUtf8(),index);

            }else if(fileInfo.isDir()){
                QString str = "*#senddirname#*" + fileInfo.fileName()+"\r\n";
                emit sendByteArray(str.toUtf8(),index);

            }

        }
    }
}



void MainWindow::init()
{

    //初始化参数
    m_tcpServer = new myTcpServer(this);

    m_type = tpType::FILELIST;


    //自动计算本机关联ipV4地址
    ui->combAddress->clear();
    QList<QHostAddress> addresses = QHostInfo::fromName(QHostInfo::localHostName()).addresses();
    for(QHostAddress address : addresses){
        if(address.protocol() == QAbstractSocket::IPv4Protocol){
            ui->combAddress->addItem(address.toString());
        }
    }

    connect(m_tcpServer,SIGNAL(newTcpSocketDescript(qintptr)),this,SLOT(onNewDescript(qintptr)));
}


void MainWindow::on_btnListen_clicked()
{

    //实现打开监听和关闭监听功能
    if(!m_tcpServer->isListening()){
        if(m_tcpServer->listen(QHostAddress(ui->combAddress->currentText()),ui->spinPort->value())){
            ui->textLog->appendPlainText("已开启监听:"+m_tcpServer->serverAddress().toString()+":"+QString::number(m_tcpServer->serverPort()));
            ui->btnListen->setText("已打开");
            ui->combAddress->setEnabled(false);
            ui->spinPort->setEnabled(false);
    }else{
        ui->textLog->appendPlainText("打开监听失败.");
        }
    }else{
        m_tcpServer->close();
        ui->textLog->appendPlainText("已关闭监听.");
        ui->btnListen->setText("已关闭");
        ui->combAddress->setEnabled(true);
        ui->spinPort->setEnabled(true);
    }
}

